home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 1
/
Cream of the Crop 1.iso
/
PROGRAM
/
VXBC15.ARJ
/
VXSAMP.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-03-07
|
39KB
|
1,086 lines
/*
┌──────────────────────────────────────────────────────────────────────────┐
│ vxBase xbase for Visual Basic library │
│ Copyright 1992 vxBase (512523 Alberta Ltd.) │
├────────────────┬──────┬────────────┬────────┬───────────────┬────────────┤
│ SYSTEM │ VX │ PROGRAM ID │ VXSAMP │ CREATION DATE │ 02/29/92 │
├────────────────┼──────┴────────────┴────────┴───────────────┴────────────┤
│ PROGRAM TITLE │ sample c program using vxbase functions from vxbase.dll│
├─────┬──────┬───┴┬───────────────────────────┬────────────────────────────┤
│ REV │ DATE │ BY │ DESCRIPTION │ Written by T. Orletsky │
├─────┼──────┼────┼───────────────────────────┴────────────────────────────┤
│ │ │ │ │
└─────┴──────┴────┴────────────────────────────────────────────────────────┘
This sample code and all other supplied sample files should be
loaded into \borlandc\vxbase to use the .def and project files
for compilation under Borland c++ (ver 2.0) from within the ide.
*/
#include <windows.h>
#include <stdlib.h>
#include <string.h>
#include <dos.h>
#include "vxb.h"
#include "vxsamp.h"
/* ********************************************************* */
/* global vars defined */
/* ********************************************************* */
HWND hgWnd; //Global Window Handle.
HANDLE hgInst; //Global Instance Handle.
int DbfArea1; //vxbase dbf area 1
int NtxArea1; //vxbase ntx area 1
int DbfArea2; //vxbase dbf area 2
int NtxArea2; //vxbase ntx area 2
long RetVal; //vxbrowse return value
char szBuffer[81]; //miscellaneous buffer
char szBuffer2[81]; //miscellaneous buffer 2
/*
* Array of pointers to strings loaded from the resource file.
* Pointers can be near since LocalAlloc will be used to get
* the string space.
*/
char NEAR *rgpsz[CSTRINGS];
/*
* WinMain
*
* Purpose:
* Main entry point of application. Should register the app class
* if a previous instance has not done so and do any other one-time
* initializations.
*
* Parameters:
* See Windows SDK Guide to Programming, page 2-3
*
* Return Value:
* Value to return to Windows--termination code.
*
*/
#pragma argsused
int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
LPSTR lpszCmdLine, int nCmdShow)
{
WNDCLASS wndClass;
HANDLE hStringMem;
HWND hWnd;
MSG msg;
hgInst = hInstance;
/*
* InitApp allocates local memory for strings. WinMain must free.
* If this fails, we should quit BEFORE any classes are registered
* or do anything else that uses up USER or GDI resources.
*/
hStringMem = HLoadAppStrings();
if (hStringMem == NULL)
{
LocalFree(hStringMem);
return FALSE;
}
if (!hPrevInstance)
{
wndClass.style = CS_HREDRAW | CS_VREDRAW;
wndClass.lpfnWndProc = vxWndProc;
wndClass.cbClsExtra = 0;
wndClass.cbWndExtra = 0;
wndClass.hInstance = hInstance;
wndClass.hIcon = LoadIcon(hInstance, "vxIcon");
wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndClass.hbrBackground = COLOR_BTNFACE + 1;
wndClass.lpszMenuName = "vxMenu";
wndClass.lpszClassName = "vxSamp";
if (!RegisterClass(&wndClass))
return FALSE;
}
hWnd = CreateWindow("vxSamp",
rgpsz[IDS_CAPTION],
WS_MINIMIZEBOX | WS_OVERLAPPEDWINDOW,
50, 50, 500, 300,
NULL,
NULL,
hInstance,
NULL);
hgWnd = hWnd;
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
LocalFree(hStringMem);
return msg.wParam;
}
/*
* vxWndProc
*
* Purpose:
* Window class procedure. Standard callback.
*
* Parameters:
* The standard. See Section 2.4 Windows SDK Guide to Programming,
* page 2-4.
*
* Return Value:
* See Parameters, above.
*
*/
#pragma argsused
long FAR PASCAL vxWndProc(HWND hWnd, unsigned iMessage,
WORD wParam, LONG lParam)
{
HMENU hMenu; // handle to main menu
int j; // work integer
PAINTSTRUCT ps; // paint structure
switch (iMessage)
{
/* handle vxBase initialization procedures when window */
/* creation message is received */
/* *************************************************** */
case WM_CREATE:
vxInit(); // register in multitask list
vxCtlGraySet(); // set up gray scale
vxBrowseCase(VX_UPPER); // default browse case
vxSetString(VX_ASCIIZ); // set string types to c strings
break;
/* on exit, reset system gray and post quit */
/* **************************************** */
case WM_DESTROY:
vxCtlGrayReset(); // reset system grays
PostQuitMessage(0); // kill
break;
/* on paint, draw frame around window */
/* ********************************** */
case WM_PAINT:
BeginPaint(hWnd, &ps);
vxFormFrame(hWnd);
EndPaint(hWnd, &ps);
break;
/* ******************************************* */
/* If user closes from system menu, ensure */
/* that multitask closure sequence is correct. */
/* The first vxbase task loaded MUST be the */
/* last one unloaded because it controls the */
/* vxbase shareable memory. If the first task */
/* is closed, the memory goes with it and any */
/* other tasks using vxbase will terminate */
/* with an Unrecoverable Application error. */
/* ******************************************* */
case WM_SYSCOMMAND:
switch (wParam & 0xFFF0)
{
case SC_CLOSE:
/* vxDeallocate will issue a task closure */
/* sequence error if this task cannot be */
/* shut down */
/* ************************************** */
if (!vxDeallocate())
return(TRUE);
/* we could use this switch set to test for */
/* other options selcted from the system menu */
/* ****************************************** */
default:
return(DefWindowProc(hWnd, iMessage, wParam, lParam));
}
/* process menu commands */
/* ********************* */
case WM_COMMAND:
switch (wParam)
{
case IDM_BROWSE:
// disable menu items
hMenu = GetMenu(hWnd);
EnableMenuItem(hMenu, IDM_BROWSE, MF_GRAYED);
EnableMenuItem(hMenu, IDM_JOIN, MF_GRAYED);
EnableMenuItem(hMenu, IDM_PACK, MF_GRAYED);
RetVal = 0;
// set up do loop and keep browsing if edit
// dialog returns a BROWSE_USER value
while (TRUE)
{
// if browse went ok, vxTypeBrowse returns nonzero
if (vxTypeBrowse())
{
if (RetVal != BROWSE_USER)
{
MessageBox(hWnd,
rgpsz[IDS_BROWSE],
rgpsz[IDS_CAPTION],
MB_OK | MB_ICONEXCLAMATION);
break;
}
}
// otherwise an error occurred
else
{
MessageBox(hWnd,
rgpsz[IDE_BROWSE],
rgpsz[IDS_CAPTION],
MB_OK | MB_ICONEXCLAMATION);
break;
}
}
// re-enable menu items
hMenu = GetMenu(hWnd);
EnableMenuItem(hMenu, IDM_BROWSE, MF_ENABLED);
EnableMenuItem(hMenu, IDM_JOIN, MF_ENABLED);
EnableMenuItem(hMenu, IDM_PACK, MF_ENABLED);
vxWindowDereg(hWnd);
break;
case IDM_JOIN:
// disable menu items
hMenu = GetMenu(hWnd);
EnableMenuItem(hMenu, IDM_BROWSE, MF_GRAYED);
EnableMenuItem(hMenu, IDM_JOIN, MF_GRAYED);
EnableMenuItem(hMenu, IDM_PACK, MF_GRAYED);
RetVal = 0;
// Demonstration of setting up visual relationships
// with the vxJoin command. What we have is a file of buyers
// categorized by type of aircraft they are interested in.
// What we are going to do is display a browse table of
// these buyer records and link any buyer record to
// another browse table of aircraft that match the the
// buyer aircraft type field.
// --------------------------------------------------------
// open file that will control the join
// ------------------------------------
DbfArea1 = vxUseDbf("\\vb\\vxbtest\\airbuyer.dbf");
NtxArea1 = vxUseNtx("\\vb\\vxbtest\\airbuy2.ntx");
// this index is on aircraft type
// ------------------------------
// define table to show data we are interested in
// ----------------------------------------------
vxTableDeclare(VX_BLUE, NULL, NULL, 0, 1, 5);
vxTableField(1, "Type", "b_cat", VX_FIELD);
vxTableField(2, "Description", "left(b_desc,20)", VX_EXPR);
vxTableField(3, "Low", "b_low", VX_FIELD);
vxTableField(4, "High", "b_high", VX_FIELD);
vxTableField(5, "Customer", "b_code", VX_FIELD);
// now open secondary file and define its table
// --------------------------------------------
DbfArea2 = vxUseDbf("\\vb\\vxbtest\\aircraft.dbf");
NtxArea2 = vxUseNtx("\\vb\\vxbtest\\aircraf2.ntx");
vxTableDeclare(VX_RED, NULL, NULL, 0, 1, 5);
vxTableField(1, "Type", "c_cat", VX_FIELD);
vxTableField(2, "Code", "c_code", VX_FIELD);
vxTableField(3, "Price", "c_price", VX_FIELD);
vxTableField(4, "Year", "c_year", VX_FIELD);
vxTableField(5, "TTSN", "c_ttsn", VX_FIELD);
// reselect the master file and set up the join
// --------------------------------------------
vxSelectDbf(DbfArea1);
vxJoin(DbfArea2, NtxArea2, "b_cat", VX_FIELD, "Possible Sales");
// this joins the Aircraft file using the index selected for
// it to the buyer file. The "b_cat" param is the field we
// will use as a key into the aircraft file and the VX_FIELD
// item tells vxBase that it is a field and not an expression.
// The last item in the call is a title for the join window.
// -----------------------------------------------------------
// now set up and execute the browse. The JOIN menu item is
// automatically enabled.
// ---------------------------------------------------------
vxBrowse(hWnd, DbfArea1, NtxArea1, FALSE, TRUE, FALSE, 0, "Buyer Details", &RetVal);
// when we return from the browse we can ignore anything
// vxBase sent back to us in the RetVal param
// -----------------------------------------------------
vxClose();
vxSelectDbf(DbfArea2);
vxClose();
vxWindowDereg(hgWnd);
// re-enable menu items
hMenu = GetMenu(hWnd);
EnableMenuItem(hMenu, IDM_BROWSE, MF_ENABLED);
EnableMenuItem(hMenu, IDM_JOIN, MF_ENABLED);
EnableMenuItem(hMenu, IDM_PACK, MF_ENABLED);
MessageBox(hgWnd,
rgpsz[IDS_JOIN],
rgpsz[IDS_CAPTION],
MB_OK | MB_ICONEXCLAMATION);
break;
case IDM_PACK:
// disable menu items
hMenu = GetMenu(hWnd);
EnableMenuItem(hMenu, IDM_BROWSE, MF_GRAYED);
EnableMenuItem(hMenu, IDM_JOIN, MF_GRAYED);
EnableMenuItem(hMenu, IDM_PACK, MF_GRAYED);
// only pack if file is not in use
j = vxAreaDbf("\\vb\vxbtest\\airtypes.dbf");
if (!j)
{
DbfArea1 = vxUseDbf("\\vb\\vxbtest\\airtypes.dbf");
NtxArea1 = vxUseNtx("\\vb\\vxbtest\\airtypes.ntx");
vxPack(hWnd);
vxClose();
MessageBox(hgWnd,
rgpsz[IDS_PACK],
rgpsz[IDS_CAPTION],
MB_OK | MB_ICONEXCLAMATION);
}
else
MessageBox(hgWnd,
rgpsz[IDE_PACK],
rgpsz[IDS_CAPTION],
MB_OK | MB_ICONEXCLAMATION);
// re-enable menu items
hMenu = GetMenu(hWnd);
EnableMenuItem(hMenu, IDM_BROWSE, MF_ENABLED);
EnableMenuItem(hMenu, IDM_JOIN, MF_ENABLED);
EnableMenuItem(hMenu, IDM_PACK, MF_ENABLED);
break;
/* see WM_SYSCOMMAND above for explanation of */
/* why we test vxDeallocate before we allow */
/* this task to be closed */
/* ****************************************** */
case IDM_EXIT:
if (!vxDeallocate())
break;
PostMessage(hWnd, WM_CLOSE, 0, 0L);
break;
}
default:
return (DefWindowProc(hWnd, iMessage, wParam, lParam));
}
return 0L;
}
/* ***************** */
/* browse types file */
/* ***************** */
int NEAR PASCAL vxTypeBrowse()
{
FARPROC lpProc; // discardable proc instance
// open dbf file
DbfArea1 = vxUseDbf("\\vb\\vxbtest\\airtypes.dbf");
if (!DbfArea1)
return (FALSE);
// open index file
NtxArea1 = vxUseNtx("\\vb\\vxbtest\\airtypes.ntx");
if (!NtxArea1)
return (FALSE);
// declare browse table
vxTableDeclare(VX_RED, NULL, NULL, 0, 1, 2);
vxTableField(1, "Type", "category", VX_FIELD);
vxTableField(2, "Description", "catname", VX_FIELD);
// set up initial browse position
vxBrowsePos(20, 10, 50, 15);
// call the browse
vxBrowse(hgWnd, DbfArea1, NtxArea1, TRUE, TRUE, TRUE, 0L, "Aircraft Types", &RetVal);
// if user closed, exit TRUE
if (RetVal == BROWSE_CLOSED)
return (TRUE);
// if browse had error, exit FALSE
if (RetVal == BROWSE_ERROR)
return (FALSE);
// if user picked anything else, do file edit dialog
// NOTE: RetVal is global so it will be accessible to
// the edit dialog
lpProc = MakeProcInstance(vxTypeEditDlg, hgInst);
DialogBox (hgInst,
MAKEINTRESOURCE (IDD_TYPEDIT),
hgWnd,
lpProc);
FreeProcInstance(lpProc);
// if user clicks browse button from dialog, retval
// is set to BROWSE_USER so calling rtn
// from wm_command can test if this is to be done again
// close file (first ensure registered)
vxSelectDbf(DbfArea1);
vxClose();
return (TRUE);
}
/* ********************************************************** */
/* Edit type file record dialog */
/* ********************************************************** */
#pragma argsused
BOOL FAR PASCAL vxTypeEditDlg(HWND hdlg, WORD wMsg, WORD wParam, LONG lParam)
{
HWND hwndDI; /* handle to dialog item */
int j; /* general integer */
static long RecNum; /* current record number */
static BOOL IsChanged; /* set if anything changes */
static BOOL IsDeleting; /* set on if deleting */
switch (wMsg)
{
// initialization routine
// **********************
case WM_INITDIALOG:
// register database select area with this window
vxSelectDbf(DbfArea1);
// set control lengths
SendDlgItemMessage(hdlg, IDD_TYPE,
EM_LIMITTEXT, (WORD)vxFieldSize("category"), 0L);
SendDlgItemMessage(hdlg, IDD_DESC,
EM_LIMITTEXT, (WORD)vxFieldSize("catname"), 0L);
SendDlgItemMessage(hdlg, IDD_STAT,
EM_LIMITTEXT, (WORD)64, 0L);
// disable status bar
hwndDI = GetDlgItem(hdlg, IDD_STAT);
EnableWindow(hwndDI, FALSE);
// other init stuff
RecNum = vxRecNo(); // save record number
szBuffer[0] = '\0'; // clear work buffer
IsChanged = FALSE; // default change val
// analyze browse return value and fill controls accordingly
// if user pressed enter key to select record for edit
if (RetVal > 0)
RetVal = BROWSE_EDIT;
// if adding, show empty record
if (RetVal == BROWSE_ADD)
{
SetDlgItemText(hdlg, IDD_TYPE, (LPSTR)szBuffer);
SetDlgItemText(hdlg, IDD_DESC, (LPSTR)szBuffer);
SetDlgItemText(hdlg, IDD_STAT, (LPSTR)rgpsz[IDS_ADDING]);
// disable add and delete buttons
hwndDI = GetDlgItem(hdlg, IDD_ADD);
EnableWindow(hwndDI, FALSE);
hwndDI = GetDlgItem(hdlg, IDD_DELETE);
EnableWindow(hwndDI, FALSE);
}
// if deleting or editing, show record
else
{
// with any vxbase string function, always copy
// the result to an internal buffer as below
// ********************************************
lstrcpy(szBuffer, (LPSTR)vxField("category"));
vxbTrim(szBuffer, sizeof(szBuffer));
SetDlgItemText(hdlg, IDD_TYPE, (LPSTR)szBuffer);
lstrcpy(szBuffer, (LPSTR)vxField("catname"));
vxbTrim(szBuffer, sizeof(szBuffer));
SetDlgItemText(hdlg, IDD_DESC, (LPSTR)szBuffer);
if (RetVal == BROWSE_DELETE)
wsprintf(szBuffer, "%s %ld", (LPSTR)rgpsz[IDS_DELE], RecNum);
else
{
wsprintf(szBuffer, "%s %ld", (LPSTR)rgpsz[IDS_EDIT], RecNum);
vxUnlock(); // unlock if editing for multiusers
}
SetDlgItemText(hdlg, IDD_STAT, (LPSTR)szBuffer);
}
// if deleting, set switch to send delete
// button click after form has been painted
if (RetVal == BROWSE_DELETE)
IsDeleting = TRUE;
// we can't send the WM_COMMAND message here
// because the dialog box hasn't been
// painted yet and we want the user to see
// the record he is deleting
return (TRUE); // sets focus to first control
// the wm_ctlcolor, wm_paint, and wm_3dpaint create
// 3d style controls on a gray background
// ************************************************
case WM_CTLCOLOR:
return (Control3dColor(hdlg,wParam));
case WM_PAINT:
PostMessage(hdlg,WM_3DPAINT,0,0L);
return (FALSE);
case WM_3DPAINT:
// frame
Draw3dFrame(hdlg,OUTSIDE_FRAME);
// edit controls
Draw3dBorder(hdlg,IDD_TYPE,RECESSED,2);
Draw3dBorder(hdlg,IDD_DESC,RECESSED,2);
Draw3dBorder(hdlg,IDD_STAT,RAISED,2);
// buttons
Draw3dBorder(hdlg,IDD_SAVE,RECESSED,2);
Draw3dBorder(hdlg,IDD_CANCEL,RECESSED,2);
Draw3dBorder(hdlg,IDD_ADD,RECESSED,2);
Draw3dBorder(hdlg,IDD_DELETE,RECESSED,2);
Draw3dBorder(hdlg,IDD_NEXT,RECESSED,2);
Draw3dBorder(hdlg,IDD_PREV,RECESSED,2);
Draw3dBorder(hdlg,IDD_BROWSE,RECESSED,2);
Draw3dBorder(hdlg,IDD_EXIT,RECESSED,2);
// if deleting, we send a message as if user punched
// delete button and we process in wm_command
if (IsDeleting)
{
IsDeleting = FALSE;
hwndDI = GetDlgItem(hdlg, IDD_DELETE);
lParam = MAKELONG(hwndDI, BN_CLICKED);
SendMessage(hdlg, WM_COMMAND, IDD_DELETE, lParam);
}
return (TRUE);
// user pressed a button
// *********************
case WM_COMMAND:
{
switch (wParam)
{
/* *********** */
/* save button */
/* *********** */
case IDD_SAVE:
// get control item "category"
GetDlgItemText(hdlg, IDD_TYPE, szBuffer, (vxFieldSize("category") + 1));
// convert to upper case and redisplay
if (lstrlen(szBuffer))
{
AnsiUpper(szBuffer);
SetDlgItemText(hdlg, IDD_TYPE, (LPSTR)szBuffer);
}
else
{
MessageBox(hdlg,
rgpsz[IDS_BADKEY],
rgpsz[IDS_CAPTION],
MB_ICONSTOP | MB_OK);
hwndDI = GetDlgItem(hdlg, IDD_TYPE);
SetFocus(hwndDI);
return (FALSE);
}
// if new item, test for duplicate key
if (RetVal == BROWSE_ADD)
{
if (vxSeek(szBuffer))
{
vxUnlock();
MessageBox(hdlg,
rgpsz[IDS_DUPKEY],
rgpsz[IDS_CAPTION],
MB_ICONSTOP | MB_OK);
hwndDI = GetDlgItem(hdlg, IDD_TYPE);
SetFocus(hwndDI);
return (FALSE);
}
// otherwise add an empty record
else
vxAppendBlank();
}
// if editing position pointer and lock record
else
vxGo(RecNum);
// get catname field data and put fields away
GetDlgItemText(hdlg, IDD_DESC, szBuffer2, (vxFieldSize("catname") + 1));
vxReplString("category", szBuffer);
vxReplString("catname", szBuffer2);
vxWrite();
// update status box
RecNum = vxRecNo();
if (RetVal == BROWSE_ADD)
wsprintf(szBuffer, "Record %ld appended", RecNum);
else
wsprintf(szBuffer, "Record %ld saved", RecNum);
SetDlgItemText(hdlg, IDD_STAT, (LPSTR)szBuffer);
// update buttons
hwndDI = GetDlgItem(hdlg, IDD_SAVE);
EnableWindow(hwndDI, TRUE);
hwndDI = GetDlgItem(hdlg, IDD_CANCEL);
EnableWindow(hwndDI, TRUE);
hwndDI = GetDlgItem(hdlg, IDD_ADD);
EnableWindow(hwndDI, TRUE);
hwndDI = GetDlgItem(hdlg, IDD_DELETE);
EnableWindow(hwndDI, TRUE);
// unlock record
vxUnlock();
// change status to edit mode
RetVal = BROWSE_EDIT;
return (TRUE);
/* ************* */
/* cancel button */
/* ************* */
case IDD_CANCEL:
// clear form data and reset buttons
szBuffer[0] = '\0'; // clear work buffer
SetDlgItemText(hdlg, IDD_TYPE, (LPSTR)szBuffer);
SetDlgItemText(hdlg, IDD_DESC, (LPSTR)szBuffer);
SetDlgItemText(hdlg, IDD_STAT, (LPSTR)rgpsz[IDS_CANC]);
hwndDI = GetDlgItem(hdlg, IDD_SAVE);
EnableWindow(hwndDI, FALSE);
hwndDI = GetDlgItem(hdlg, IDD_CANCEL);
EnableWindow(hwndDI, FALSE);
hwndDI = GetDlgItem(hdlg, IDD_ADD);
EnableWindow(hwndDI, TRUE);
hwndDI = GetDlgItem(hdlg, IDD_DELETE);
EnableWindow(hwndDI, FALSE);
// disable data entry
hwndDI = GetDlgItem(hdlg, IDD_TYPE);
EnableWindow(hwndDI, TRUE);
hwndDI = GetDlgItem(hdlg, IDD_DESC);
EnableWindow(hwndDI, TRUE);
return (TRUE);
/* ********** */
/* add button */
/* ********** */
case IDD_ADD:
// test if current stuff has changed
for (j=IDD_TYPE; j<IDD_DESC; j++)
if (SendDlgItemMessage(hdlg, j, EM_GETMODIFY, 0, 0L))
IsChanged = TRUE;
if (IsChanged)
{
IsChanged = FALSE;
if (IDNO == (MessageBox(hdlg, "Current record changed. Abandon?",
rgpsz[IDS_CAPTION],
MB_ICONQUESTION | MB_YESNO)))
return (TRUE);
}
IsChanged = FALSE;
// clear controls
szBuffer[0] = '\0'; // clear work buffer
SetDlgItemText(hdlg, IDD_TYPE, (LPSTR)szBuffer);
SetDlgItemText(hdlg, IDD_DESC, (LPSTR)szBuffer);
SetDlgItemText(hdlg, IDD_STAT, (LPSTR)rgpsz[IDS_ADDING]);
// disable add and delete buttons
hwndDI = GetDlgItem(hdlg, IDD_ADD);
EnableWindow(hwndDI, FALSE);
hwndDI = GetDlgItem(hdlg, IDD_DELETE);
EnableWindow(hwndDI, FALSE);
// enable data entry
hwndDI = GetDlgItem(hdlg, IDD_TYPE);
EnableWindow(hwndDI, TRUE);
hwndDI = GetDlgItem(hdlg, IDD_DESC);
EnableWindow(hwndDI, TRUE);
// set add mode
RetVal = BROWSE_ADD;
// set focus to code
hwndDI = GetDlgItem(hdlg, IDD_TYPE);
SetFocus(hwndDI);
// when setting focus, always return false
return (FALSE);
/* ************* */
/* delete button */
/* ************* */
case IDD_DELETE:
// confirm deletion
if (IDNO == (MessageBox(hdlg,
rgpsz[IDS_CDELE],
rgpsz[IDS_CAPTION],
MB_ICONQUESTION | MB_YESNO)))
{
SetDlgItemText(hdlg, IDD_STAT, "Delete cancelled");
RetVal = BROWSE_EDIT;
return (TRUE);
}
vxLockRecord();
vxDeleteRec();
wsprintf(szBuffer, "Record %ld deleted", RecNum);
SetDlgItemText(hdlg, IDD_STAT, (LPSTR)szBuffer);
// clear data and reset buttons
szBuffer[0] = '\0'; // clear work buffer
SetDlgItemText(hdlg, IDD_TYPE, (LPSTR)szBuffer);
SetDlgItemText(hdlg, IDD_DESC, (LPSTR)szBuffer);
hwndDI = GetDlgItem(hdlg, IDD_SAVE);
EnableWindow(hwndDI, FALSE);
hwndDI = GetDlgItem(hdlg, IDD_CANCEL);
EnableWindow(hwndDI, FALSE);
hwndDI = GetDlgItem(hdlg, IDD_ADD);
EnableWindow(hwndDI, TRUE);
hwndDI = GetDlgItem(hdlg, IDD_DELETE);
EnableWindow(hwndDI, FALSE);
// disable data entry
hwndDI = GetDlgItem(hdlg, IDD_TYPE);
EnableWindow(hwndDI, TRUE);
hwndDI = GetDlgItem(hdlg, IDD_DESC);
EnableWindow(hwndDI, TRUE);
RetVal = 0;
vxUnlock();
return (TRUE);
/* *********** */
/* next button */
/* *********** */
case IDD_NEXT:
// first test if current rec has changed
for (j=IDD_TYPE; j<IDD_DESC; j++)
if (SendDlgItemMessage(hdlg, j, EM_GETMODIFY, 0, 0L))
IsChanged = TRUE;
if (IsChanged)
{
IsChanged = FALSE;
if (IDNO == (MessageBox(hdlg, "Current record changed. Abandon?",
rgpsz[IDS_CAPTION],
MB_ICONQUESTION | MB_YESNO)))
return (TRUE);
}
IsChanged = FALSE;
// skip unless eof; ignore deleted records
while (TRUE)
{
vxSkip(1L);
if (vxEof())
break;
if (!vxDeleted())
break;
}
if (vxEof())
{
MessageBeep(0);
SetDlgItemText(hdlg, IDD_STAT, "End of file");
vxBottom();
RecNum = vxRecNo();
}
else
{
RecNum = vxRecNo();
wsprintf(szBuffer, "Skipped to record %ld", RecNum);
SetDlgItemText(hdlg, IDD_STAT, (LPSTR)szBuffer);
}
lstrcpy(szBuffer, (LPSTR)vxField("category"));
vxbTrim(szBuffer, sizeof(szBuffer));
SetDlgItemText(hdlg, IDD_TYPE, (LPSTR)szBuffer);
lstrcpy(szBuffer, (LPSTR)vxField("catname"));
vxbTrim(szBuffer, sizeof(szBuffer));
SetDlgItemText(hdlg, IDD_DESC, (LPSTR)szBuffer);
RetVal = BROWSE_EDIT;
hwndDI = GetDlgItem(hdlg, IDD_SAVE);
EnableWindow(hwndDI, TRUE);
hwndDI = GetDlgItem(hdlg, IDD_CANCEL);
EnableWindow(hwndDI, TRUE);
hwndDI = GetDlgItem(hdlg, IDD_ADD);
EnableWindow(hwndDI, TRUE);
hwndDI = GetDlgItem(hdlg, IDD_DELETE);
EnableWindow(hwndDI, TRUE);
// set focus to code
hwndDI = GetDlgItem(hdlg, IDD_TYPE);
SetFocus(hwndDI);
return (FALSE);
/* *********** */
/* prev button */
/* *********** */
case IDD_PREV:
// first test if current rec has changed
for (j=IDD_TYPE; j<IDD_DESC; j++)
if (SendDlgItemMessage(hdlg, j, EM_GETMODIFY, 0, 0L))
IsChanged = TRUE;
if (IsChanged)
{
IsChanged = FALSE;
if (IDNO == (MessageBox(hdlg, "Current record changed. Abandon?",
rgpsz[IDS_CAPTION],
MB_ICONQUESTION | MB_YESNO)))
return (TRUE);
}
IsChanged = FALSE;
// skip unless bof; ignore deleted records
while (TRUE)
{
vxSkip(-1L);
if (vxBof())
break;
if (!vxDeleted())
break;
}
if (vxBof())
{
MessageBeep(0);
SetDlgItemText(hdlg, IDD_STAT, "Beginning of file");
vxTop();
RecNum = vxRecNo();
}
else
{
RecNum = vxRecNo();
wsprintf(szBuffer, "Skipped to record %ld", RecNum);
SetDlgItemText(hdlg, IDD_STAT, (LPSTR)szBuffer);
}
// load data
lstrcpy(szBuffer, (LPSTR)vxField("category"));
vxbTrim(szBuffer, sizeof(szBuffer));
SetDlgItemText(hdlg, IDD_TYPE, (LPSTR)szBuffer);
lstrcpy(szBuffer, (LPSTR)vxField("catname"));
vxbTrim(szBuffer, sizeof(szBuffer));
SetDlgItemText(hdlg, IDD_DESC, (LPSTR)szBuffer);
RetVal = BROWSE_EDIT;
// reset buttons
hwndDI = GetDlgItem(hdlg, IDD_SAVE);
EnableWindow(hwndDI, TRUE);
hwndDI = GetDlgItem(hdlg, IDD_CANCEL);
EnableWindow(hwndDI, TRUE);
hwndDI = GetDlgItem(hdlg, IDD_ADD);
EnableWindow(hwndDI, TRUE);
hwndDI = GetDlgItem(hdlg, IDD_DELETE);
EnableWindow(hwndDI, TRUE);
// set focus to code
hwndDI = GetDlgItem(hdlg, IDD_TYPE);
SetFocus(hwndDI);
return (FALSE);
/* ************* */
/* browse button */
/* ************* */
case IDD_BROWSE:
// first test if current rec has changed
for (j=IDD_TYPE; j<IDD_DESC; j++)
if (SendDlgItemMessage(hdlg, j, EM_GETMODIFY, 0, 0L))
IsChanged = TRUE;
if (IsChanged)
{
IsChanged = FALSE;
if (IDNO == (MessageBox(hdlg, "Current record changed. Abandon?",
rgpsz[IDS_CAPTION],
MB_ICONQUESTION | MB_YESNO)))
return (TRUE);
}
RetVal = BROWSE_USER;
EndDialog(hdlg, TRUE);
return (TRUE);
/* *********** */
/* exit button */
/* *********** */
case IDD_EXIT:
// first test if current rec has changed
for (j=IDD_TYPE; j<IDD_DESC; j++)
if (SendDlgItemMessage(hdlg, j, EM_GETMODIFY, 0, 0L))
IsChanged = TRUE;
if (IsChanged)
{
IsChanged = FALSE;
if (IDNO == (MessageBox(hdlg, "Current record changed. Abandon?",
rgpsz[IDS_CAPTION],
MB_ICONQUESTION | MB_YESNO)))
return (TRUE);
}
RetVal = 0; // clear RetVal before return
EndDialog(hdlg, TRUE);
return (TRUE);
}
}
default:
break;
}
return (FALSE);
}
/* ************************************************************
* HLoadAppStrings
*
* Purpose:
* Allocates FIXED local memory and reads the applications
* string resources into that memory. Each string's pointer
* is available with rgpsz[i] where i is the ID value of the
* string. The strings must have sequential IDs.
*
* Parameters:
* none
*
* Return Value:
* HANDLE Handle to the local memory. NULL if memory could
* not be allocated.
*
* ************************************************************ */
HANDLE NEAR PASCAL HLoadAppStrings(void)
{
HANDLE hLocalMem;
char NEAR *pch;
WORD cchUsed = 0;
WORD cch;
short i;
/*
* Allocate memory and load strings. NOTE! The LPTR style
* specifies FIXED memory. This should not be a big deal
* since this is an early allocation into the local heap.
* But it should be watched if the number of strings becomes
* large.
*/
hLocalMem = LocalAlloc(LPTR, CSTRINGS*CCHSTRINGMAX);
if (hLocalMem == NULL)
return (HANDLE)NULL;
/*
* This operation is only valid for FIXED memory. Otherwise use
* LocalLock.
*/
pch = (char *)hLocalMem;
/*
* Load the strings into the memory and retain the specific
* pointer to that string.
*/
for (i = 0; i < CSTRINGS; i++)
{
cch = LoadString(hgInst, i, (LPSTR)(pch + cchUsed), CCHSTRINGMAX - 1);
rgpsz[i] = (char *)(pch + cchUsed);
/*
* One is added to cch to include a NULL. The memory was ZEROINITed
* on allocation so by skipping a byte we get the NULL.
*/
cchUsed += (cch + 1);
}
/*
* It is assumed that no string is over CCHSTRINGMAX, and therefore
* not all the allocated memory was used. Therefore LocalReAlloc
* will only SHRINK the block, never expand it. So if it fails, there's
* no problem--all the strings are still there, with some wasted
* space.
*/
LocalReAlloc(hLocalMem, cchUsed+1, LPTR);
return hLocalMem;
}
/*
┌──────────────────────────────────────────────────────────────────────────┐
│ END │
└──────────────────────────────────────────────────────────────────────────┘
*/